<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>状态过渡</title>
    <script src="../vue.js"></script>
    <style type="text/css">
      .app2-color-preview {
        display: inline-block;
        width: 50px;
        height: 50px;
      }
    
    </style>
  </head>
  <body>
    <!-- 1 状态动画与侦听器 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.2.4/gsap.min.js"></script>
    <div id="animated-number-demo" style="border: 1px dashed blue;margin-bottom: 2px;">
      <input v-model.number="number" type="number" step="20" />
      <p>{{animatedNumber}}</p>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/tween.js@16.3.4"></script>
    <script src="https://cdn.jsdelivr.net/npm/color-js@1.0.3"></script>
    <div id="app2" style="border: 1px dashed red;margin-bottom: 2px;">
      <input v-model="colorQuery"
        @keyup.enter="updateColor"
        placeholder="Enter a color"
      >
      <button @click="updateColor">Update</button>
      <p>Preview: </p>
      <span
        :style="{backgroundColor: tweenedCSSColor}"
        class="app2-color-preview"
      ></span>
      <p>{{tweenedCSSColor}}</p>
    </div>
    
    <!-- 2 动态状态过渡 -->
    <!-- 3 把过渡放到组件里 -->
    <script src="https://cdn.jsdelivr.net/npm/tween.js@16.3.4"></script>
    <div id="app3" style="border: 1px dashed green;margin-bottom: 2px;">
      <input v-model.number="firstNumber" type="number" step="20" /> + 
      <input v-model.number="secondNumber" type="number" step="20" /> = 
      {{result}}
      <p>
        <animated-integer :value="firstNumber"></animated-integer> + 
        <animated-integer :value="secondNumber"></animated-integer> = 
        <animated-integer :value="result"></animated-integer>
      </p>
    </div>
    <!-- 4 赋予设计以生命 -->
    <script type="text/javascript">
      // 1 状态动画与侦听器
      new Vue({
        el: '#animated-number-demo',
        data: {
          number: 0,
          tweenedNumber: 0
        },
        computed: {
          animatedNumber: function() {
            return this.tweenedNumber.toFixed(0)
          }
        },
        watch: {
          number: function(newValue) {
            gsap.to(this.$data, {duration: 0.5, tweenedNumber: newValue})
          }
        }
      })
      /* -------------------------------- */
      var Color = net.brehaut.Color
      new Vue({
        el: '#app2',
        data: {
          colorQuery: '',
          color: {
            red: 0,
            green: 0, 
            blue: 0, 
            alpha: 1
          },
          tweenedColor: {}
        },
        created: function() {
          this.tweenedColor = Object.assign({}, this.color)
        },
        watch: {
          color: function() {
            function animate() {
              if(TWEEN.update()) {
                requestAnimationFrame(animate)
              }
            }
            
            new TWEEN.Tween(this.tweenedColor)
              .to(this.color, 750)
              .start()
            
            animate()
          }
        },
        computed: {
          tweenedCSSColor: function() {
            return new Color({
              red: this.tweenedColor.red,
              green: this.tweenedColor.green,
              blue: this.tweenedColor.blue,
              alpha: this.tweenedColor.alpha
            }).toCSS()
          }
        },
        methods: {
          updateColor: function() {
            this.color = new Color(this.colorQuery).toRGB()
            this.colorQuery = ''
          }
        }
      })
      
      /* -------------------------------- */
      
      // 2 动态状态过渡
      // 3 把过渡放到组件里
      /* 这种复杂的补间动画逻辑可以被复用
      任何整数都可以执行动画
      组件化使我们的界面十分清晰
      可以支持更多更复杂的动态过渡策略。 */
      Vue.component('animated-integer', {
        template: '<span>{{tweeningValue}}</span>',
        props: {
          value: {
            type: Number,
            required: true
          }
        },
        data: function() {
          return {
            tweeningValue: 0
          }
        },
        watch: {
          value: function(newValue, oldValue) {
            this.tween(0, this.value)
          }
        },
        methods: {
          tween: function(startValue, endValue) {
            var vm = this
            function animate() {
              if (TWEEN.update()) {
                requestAnimationFrame(animate)
              }
            }
            
            new TWEEN.Tween({ tweeningValue: startValue })
            .to({tweeningValue: endValue}, 500)
            .onUpdate(function() {
              vm.tweeningValue = this.tweeningValue.toFixed(0)
            })
            .start()
            
            animate()
          }
        }
      })
      // 所有的复杂度都已经从 Vue 的主实例中移除！
      new Vue({
        el: '#app3',
        data: {
          firstNumber: 0,
          secondNumber: 0
        },
        computed: {
          result: function() {
            return this.firstNumber + this.secondNumber
          }
        }
      })
      // 我们能在组件中结合使用这一节讲到各种过渡策略和 Vue 内建的过渡系统。总之，对于完成各种过渡动效几乎没有阻碍。
      
      // 4 赋予设计以生命
    </script>
  </body>
</html>
